package com.hk.core.autoconfigure.exception.reactive;

import org.springframework.boot.autoconfigure.web.ErrorProperties;
import org.springframework.boot.autoconfigure.web.WebProperties;
import org.springframework.boot.autoconfigure.web.reactive.error.DefaultErrorWebExceptionHandler;
import org.springframework.boot.web.reactive.error.ErrorAttributes;
import org.springframework.context.ApplicationContext;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;


/**
 * <pre>
 *
 * 使用 Spring 定义的接口处理异常,继承 spring定义 的接口，重写指定逻辑即可。
 *
 * rest json result 错误解析器
 * </pre>
 *
 * @author Kevin
 * @see JsonResultErrorAttributes
 * @see org.springframework.boot.autoconfigure.web.reactive.error.DefaultErrorWebExceptionHandler
 */
public class JsonResultErrorWebExceptionHandler extends DefaultErrorWebExceptionHandler {

    public JsonResultErrorWebExceptionHandler(ErrorAttributes errorAttributes, WebProperties.Resources resources,
                                              ErrorProperties errorProperties, ApplicationContext applicationContext) {
        super(errorAttributes, resources, errorProperties, applicationContext);
    }

    @Override
    public Mono<Void> handle(ServerWebExchange exchange, Throwable throwable) {
        AbstractExceptionHandler.error(throwable, throwable.getMessage(), exchange);
        return super.handle(exchange, throwable);
    }


    @Override
    protected Mono<ServerResponse> renderErrorResponse(ServerRequest request) {
        var error = getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.ALL));
        var httpStatus = getHttpStatus(error);
        error.remove("status");
        return ServerResponse.status(httpStatus).contentType(MediaType.APPLICATION_JSON)
                .body(BodyInserters.fromValue(error));
    }
}
